home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d18
/
pibcat.arc
/
PIBCATZ.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1989-03-31
|
20KB
|
392 lines
(*----------------------------------------------------------------------*)
(* Display_ZOO_Contents --- Display contents of .ZOO file *)
(*----------------------------------------------------------------------*)
PROCEDURE Display_ZOO_Contents( ZOOFileName : AnyStr );
(*----------------------------------------------------------------------*)
(* *)
(* Procedure: Display_ZOO_Contents *)
(* *)
(* Purpose: Displays contents of a .ZOO file *)
(* *)
(* Calling sequence: *)
(* *)
(* Display_ZOO_Contents( ZOOFileName : AnyStr ); *)
(* *)
(* ZOOFileName --- name of .ZOO file whose contents *)
(* are to be listed. *)
(* *)
(* Calls: *)
(* *)
(* Aside from internal subroutines, these routines are required: *)
(* *)
(* Dir_Convert_Date_And_Time *)
(* --- convert DOS packed date/time to string*)
(* Open_File --- open a file *)
(* Close_File --- close a file *)
(* Entry_Matches --- Perform wildcard match *)
(* Display_Page_Titles *)
(* --- Display titles at top of page *)
(* DUPL --- Duplicate a character into a string *)
(* *)
(*----------------------------------------------------------------------*)
(*----------------------------------------------------------------------*)
(* Maps of ZOO file headers and entries *)
(*----------------------------------------------------------------------*)
CONST
PATHSIZE = 256 (* Max length of pathname *);
FNAMESIZE = 13 (* Size of DOS filename *);
LFNAMESIZE = 256 (* Size of long filename *);
SIZ_TEXT = 20 (* Length of header text *);
Valid_ZOO = $FDC4A7DC (* Valid ZOO tag *);
TYPE
Header_Text_Type = ARRAY[ 1 .. SIZ_TEXT ] OF CHAR;
FName_Type = ARRAY[ 1 .. FNAMESIZE ] OF CHAR;
LFname_Type = ARRAY[ 1 .. LFNAMESIZE ] OF CHAR;
Path_Type = ARRAY[ 1 .. PATHSIZE ] OF CHAR;
(* ZOO file header *)
ZOO_Header_Type = RECORD
Header_Text : Header_Text_Type (* Character text *);
ZOO_Tag : LONGINT (* Identifies archives *);
ZOO_Start : LONGINT (* Where data starts *);
ZOO_Minus : LONGINT (* Consistency check *);
ZOO_Major : CHAR (* Major version # *);
ZOO_Minor : CHAR (* Minor version # *);
END;
(* One entry in ZOO library *)
(* Fixed part of entry *)
ZOO_Fixed_Type = RECORD
(* Fixed part of entry *)
ZOO_Tag : LONGINT (* Tag -- redundancy check *);
ZOO_Type : BYTE (* Type of directory entry *);
Pack_Method : BYTE (* 0 = no packing, 1 = normal LZW *);
Next : LONGINT (* Pos'n of next directory entry *);
Offset : LONGINT (* Position of this file *);
Date : WORD (* DOS format date *);
Time : WORD (* DOS format time *);
File_CRC : WORD (* CRC of this file *);
Org_Size : LONGINT (* Original file size *);
Size_Now : LONGINT (* Compressed file size *);
Major_Ver : BYTE (* Version required to extract ... *);
Minor_Ver : BYTE (* this file (minimum) *);
Deleted : BYTE (* Will be 1 if deleted, 0 if not *);
Struc : BYTE (* File structure if any *);
Comment : LONGINT (* Points to comment; zero if none *);
Cmt_Size : WORD (* Length of comment, 0 if none *);
FName : FName_Type (* Filename *);
Var_Dir_Len : INTEGER (* Length of variable part of dir entry *);
Time_Zone : BYTE (* Time zone where file was created *);
Dir_CRC : WORD (* CRC of directory entry *);
END;
(* Variable part of entry *)
ZOO_Varying_Type = ARRAY[1..4+PATHSIZE+LFNAMESIZE] OF CHAR;
(* Varying field definitions follow *)
(* for descriptive purposes. Any or *)
(* all of these can be missing, *)
(* depending upon the setting of *)
(* Var_Dir_Len above and NamLen and *)
(* DirLen here. *)
VAR
NamLen : BYTE (* Length of long filename *);
DirLen : BYTE (* Length of directory name *);
System_ID : INTEGER (* Filesystem ID *);
VAR
ZOOFile : FILE (* ZOO file to be read *);
ZOO_Header : ZOO_Header_Type (* Header for ZOO file *);
ZOO_Entry : ZOO_Fixed_Type (* Entry for one file in ZOO file *);
ZOO_Varying : ZOO_Varying_Type (* Varying part of ZOO entry *);
ZOO_Pos : LONGINT (* Current byte offset in ZOO file *);
Bytes_Read : INTEGER (* # bytes read from ZOO file *);
Ierr : INTEGER (* Error flag *);
Long_Name : AnyStr (* Long file name *);
(*----------------------------------------------------------------------*)
(* Get_ZOO_Header --- Get initial header entry in ZOO file *)
(*----------------------------------------------------------------------*)
FUNCTION Get_ZOO_Header( VAR Error : INTEGER ) : BOOLEAN;
(*----------------------------------------------------------------------*)
(* *)
(* Function: Get_ZOO_Header *)
(* *)
(* Purpose: Gets initial ZOO header *)
(* *)
(* Calling sequence: *)
(* *)
(* OK := Get_ZOO_Header( VAR Error : INTEGER ) : BOOLEAN; *)
(* *)
(* ZOOEntry --- Header data for next file in ZOO file *)
(* Error --- Error flag *)
(* OK --- TRUE if header successfully found, else FALSE *)
(* *)
(*----------------------------------------------------------------------*)
BEGIN (* Get_ZOO_Header *)
(* Assume no error to start *)
Error := 0;
(* Read in the file header entry. *)
BlockRead( ZOOFile, ZOO_Header, SizeOf( ZOO_Header ), Bytes_Read );
Error := 0;
(* If we didn't read enough, assume *)
(* it's not a ZOO file at all. *)
IF ( Bytes_Read < SizeOf( ZOO_Header ) ) THEN
Error := Format_Error
(* Check signature. If wrong, then *)
(* file is bad or not an ZOO file at *)
(* all. *)
ELSE IF ( ZOO_Header.ZOO_Tag <> Valid_ZOO ) THEN
Error := Format_Error
ELSE (* Header looks ok -- we got *)
(* the entry data. Position to *)
(* first file entry *)
WITH ZOO_Entry DO
ZOO_Pos := ZOO_Header.ZOO_Start;
(* Report success/failure to calling *)
(* routine. *)
Get_ZOO_Header := ( Error = 0 );
END (* Get_ZOO_Header *);
(*----------------------------------------------------------------------*)
(* Get_Next_ZOO_Entry --- Get next file entry in ZOO file *)
(*----------------------------------------------------------------------*)
FUNCTION Get_Next_ZOO_Entry( VAR ZOO_Entry : ZOO_Fixed_Type;
VAR Error : INTEGER ) : BOOLEAN;
(*----------------------------------------------------------------------*)
(* *)
(* Function: Get_Next_ZOO_Entry *)
(* *)
(* Purpose: Gets header information for next file in ZOO file *)
(* *)
(* Calling sequence: *)
(* *)
(* OK := Get_Next_ZOO_Entry( VAR ZOO_Entry : ZOO_Fixed_Type; *)
(* VAR Error : INTEGER ); *)
(* *)
(* ZOO_Entry --- Header data for next file in ZOO file *)
(* Error --- Error flag *)
(* OK --- TRUE if header successfully found, else FALSE *)
(* *)
(*----------------------------------------------------------------------*)
BEGIN (* Get_Next_ZOO_Entry *)
(* Assume no error to start *)
Error := 0;
(* Position to file entry *)
Seek( ZOOFile, ZOO_Pos );
(* Read in the file header entry. *)
BlockRead( ZOOFile, ZOO_Entry, SizeOf( ZOO_Entry ), Bytes_Read );
Error := 0;
(* If we didn't read enough, assume *)
(* an error. *)
IF ( Bytes_Read < SizeOf( ZOO_Entry ) ) THEN
Error := Format_Error
(* Check signature. If wrong, then *)
(* file is bad or not an ZOO file at *)
(* all. *)
ELSE IF ( ZOO_Entry.ZOO_Tag <> Valid_ZOO ) THEN
Error := Format_Error
ELSE (* Header looks ok -- we got *)
(* the entry data. Position to *)
(* next header. *)
BEGIN
ZOO_Pos := ZOO_Entry.Next;
IF ( ZOO_Pos = 0 ) THEN
Error := End_Of_File;
END;
(* Report success/failure to calling *)
(* routine. *)
Get_Next_ZOO_Entry := ( Error = 0 );
END (* Get_Next_ZOO_Entry *);
(*----------------------------------------------------------------------*)
(* Display_ZOO_Entry --- Display ZOO entry *)
(*----------------------------------------------------------------------*)
PROCEDURE Display_ZOO_Entry( ZOO_Entry : ZOO_Fixed_Type );
VAR
FileName : AnyStr;
DirectName : AnyStr;
TimeDate : LONGINT;
TimeDateW : ARRAY[1..2] OF WORD ABSOLUTE TimeDate;
DelFile : BOOLEAN;
BEGIN (* Display_ZOO_Entry *)
WITH ZOO_Entry DO
BEGIN
(* Pick up file name *)
FileName := COPY( FName, 1, PRED( POS( #0 , FName ) ) );
(* See if this file matches the *)
(* entry spec wildcard. Exit if *)
(* not. *)
IF Use_Entry_Spec THEN
IF ( NOT Entry_Matches( FileName ) ) THEN
EXIT;
(* Get date and time of creation *)
TimeDateW[1] := Time;
TimeDateW[2] := Date;
(* Note if deleted entry *)
DelFile := ( Deleted = 1 );
(* Pick up long file name. *)
Long_Name := '';
IF ( DelFile ) THEN
Long_Name := ' (Deleted)'
ELSE
(* Display long file name if requested *)
IF ( Show_Long_File_Names AND ( Var_Dir_Len > 0 ) ) THEN
BEGIN
(* Read varying part *)
BlockRead( ZOOFile, ZOO_Varying, Var_Dir_Len, Bytes_Read );
IF ( Bytes_Read = Var_Dir_Len ) THEN
BEGIN
(* Watch out -- assumes string[0] *)
(* contains length of string. *)
(* Get directory size and long file *)
(* name size. *)
NamLen := ORD( ZOO_Varying[ 1 ] );
DirLen := ORD( ZOO_Varying[ 2 ] );
(* Pick up system ID if we have one. *)
(* Note MOVE used to extract data from *)
(* varying part of record here too. *)
IF ( ( NamLen + DirLen + 2 ) < Var_Dir_Len ) THEN
MOVE( ZOO_Varying[ NamLen + DirLen + 3 ], System_ID, 2 )
ELSE
System_ID := 4095;
(* Skip this stuff if we have neither. *)
IF ( ( DirLen > 0 ) OR ( NamLen > 0 ) ) THEN
BEGIN
(* Get long name. If none, just *)
(* use short name again. Note -- *)
(* we get 1 less than specified *)
(* length, since directory and *)
(* names are stored with trailing *)
(* #0 = ascii Z string format. *)
IF ( NamLen > 0 ) THEN
BEGIN
MOVE( ZOO_Varying[ 3 ] , FileName[ 1 ] , PRED( NamLen ) );
FileName[ 0 ] := CHR( PRED( NamLen ) );
END
ELSE
FileName := COPY( FName, 1, PRED( POS( #0 , FName ) ) );
(* Get directory name *)
IF ( DirLen > 0 ) THEN
BEGIN
MOVE( ZOO_Varying[ 3 + NamLen ] , DirectName[ 1 ] , PRED( DirLen ) );
DirectName[ 0 ] := CHR( PRED( DirLen ) );
(* Append trailing '/' if missing and *)
(* system ID indicates we should *)
IF ( System_ID <= 2 ) THEN
IF ( DirectName[ LENGTH( DirectName ) ] <> '/' ) THEN
DirectName := DirectName + '/';
END
ELSE
DirectName := '';
(* Write directory and file name *)
Long_Name := DirectName + FileName;
END;
END;
END;
(* Display info for this entry *)
Display_One_Entry( FileName, Org_Size, TimeDate, ZOOFileName,
Current_Subdirectory, Long_Name );
(* Decrement file count, total bytes *)
(* if file a deleted entry. *)
IF ( NOT DelFile ) THEN
BEGIN
(* Increment total space used *)
Total_ESpace := Total_ESpace + Org_Size;
(* Increment total entry count *)
INC( Total_Entries );
END;
END;
END (* Display_ZOO_Entry *);
(*----------------------------------------------------------------------*)
BEGIN (* Display_ZOO_Contents *)
(* Open library file and initialize *)
(* contents display. *)
IF Start_Contents_Listing( ' ZOO file: ',
Current_Subdirectory + ZOOFileName, ZOOFile,
ZOO_Pos, Ierr ) THEN
BEGIN
(* Loop over entries in ZOO file *)
IF Get_ZOO_Header( Ierr ) THEN
WHILE( Get_Next_ZOO_Entry( ZOO_Entry , Ierr ) ) DO
Display_ZOO_Entry( ZOO_Entry );
(* Close ZOO file *)
End_Contents_Listing( ZOOFile , Ierr );
END;
END (* Display_ZOO_Contents *);